﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.Configuration;
using System.Xml;

namespace EIA.WCFSecurity
{
    public class InspectTokenBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        public const string CONFIGKEY_TOKEN_HEAD_NAME = "EIA.WCFSecurity.TokenHeaderName";
        public const string CONFIGKEY_TOKEN_HEAD_NAMESPACE = "EIA.WCFSecurity.TokenHeaderNamespace";

        public InspectTokenBehavior()
        {
        }

        #region BehaviorExtensionElement

        public override Type BehaviorType
        {
            get { return typeof(InspectTokenBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new InspectTokenBehavior();
        }

        #endregion

        #region IEndpointBehavior 成员

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            throw new NotImplementedException();
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            DispatchTokenInspector inspector = new DispatchTokenInspector();
            string tokenHeaderName = TryGetAppSetting(this.GetType(), CONFIGKEY_TOKEN_HEAD_NAME);
            string tokenHeaderNamespace = TryGetAppSetting(this.GetType(), CONFIGKEY_TOKEN_HEAD_NAMESPACE);
            inspector.TokenHeadName = tokenHeaderName;
            inspector.TokenHeadNamespace = tokenHeaderNamespace;
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        #endregion

        private static string TryGetAppSetting(Type type, string key)
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);
            if (config.AppSettings.Settings.AllKeys.Contains(key))
            {
                return config.AppSettings.Settings[key].Value;
            }
            else
            {
                return ConfigurationManager.AppSettings[key];
            }
        }
    }
}